package http

import (
	"context"
	"crypto/tls"
	"errors"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
)

// BiSvr 结构体代表一个双向服务器。
// 它可以通过接收请求体，处理后返回一个响应体。
type BiSvr struct {
	id         int                                            // 表示服务id
	server     *http.Server                                   // 指向一个http.Server，用于处理HTTP请求
	addr       string                                         // 存储服务器的地址信息，格式为"host:port"
	f          func(r any, rbody string, wbody *string) error // 处理函数，接收请求体字符串和指向响应体字符串的指针，处理请求并生成响应。
	xmlNS      string                                         // 存储SU的XML命名空间
	path       string                                         // 存储服务器的URL路径
	enableTLS  bool                                           //是否启用TLS
	EnableSoap bool                                           // 是否启用SOAPAction，默认为false。
}

// NewBiSvr 创建并返回一个新的BiSvr实例。
//
// 参数:
//
//	addr - 服务器地址。
//	xmlNS - XML服务唯一标识符。
//	path - 服务路径。
//	enableTLS - 是否启用TLS连接。
//	f - 自定义的处理函数，接收请求体和响应体作为参数，并返回错误。
//
// 返回值:
//
//	返回初始化后的BiSvr指针。
func NewBiSvr(addr string, xmlNS string, path string, enableTLS bool, EnableSoap bool, f func(r any, rbody string, wbody *string) error) *BiSvr {
	return &BiSvr{
		addr:       addr,
		f:          f,
		xmlNS:      xmlNS,
		path:       path,
		enableTLS:  enableTLS,
		EnableSoap: EnableSoap,
	}
}

// SetCB 设置回调函数
// 参数:
//
//	f: 一个函数，接收两个参数，一个是请求体字符串rbody，另一个是指向响应体字符串的指针wbody，返回一个错误值。
//
// 描述:
//
//	此函数用于设置一个回调函数，该回调函数会在特定事件发生时被调用。
func (p *BiSvr) SetCB(f func(r any, rbody string, wbody *string) error) {
	p.f = f // 保存回调函数到BiSvr实例中
}

// handler 是HTTP请求处理函数。
func (p *BiSvr) handler(w http.ResponseWriter, r *http.Request) {
	// 解析请求体
	defer r.Body.Close()
	body, err := io.ReadAll(r.Body)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

	// 解析请求体XML数据
	// resp, err := ParseReqXMLData(string(body))
	// if err != nil {
	// 	fmt.Printf("GetRespXmlData Error: %s", err)
	// 	http.Error(w, "Internal Server Error:GetRespXmlData Error", http.StatusInternalServerError)
	// 	return
	// }

	// 如果定义了处理函数f，则调用f处理响应
	if p.f != nil {
		var wStr string
		err := p.f(r, string(body), &wStr)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		// fmt.Printf("wStr:\n%s\n", wStr)
		// resp, _ := GenRespSXMLData(p.xmlSUNamespace, wStr)
		// fmt.Printf("resp:\n%s\n", wStr)
		fmt.Fprintf(w, "%s", wStr)
		return
	}

	// 未定义处理函数时返回500内部服务器错误
	http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}

// // HandlerFunc 为双向服务器设置处理函数。
// func (p *BiSvr) HandlerFunc(f func(rbody string, wbody *string) error) {
// 	p.f = f
// }

// Start 启动双向服务器。
func (p *BiSvr) Start() error {
	// 监听指定地址
	listener, err := net.Listen("tcp", p.addr)
	if err != nil {
		return fmt.Errorf("failed to listen on address %s: %w", p.addr, err)
	}
	fmt.Printf("listening on %s path:%s\n", p.addr, p.path)
	http.HandleFunc(p.path, p.handler)

	if p.enableTLS && p.EnableSoap == false {
		// 加载证书和密钥
		cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
		if err != nil {
			return fmt.Errorf("failed to load certificate and key: %w", err)
		}

		p.server = &http.Server{
			Addr: p.addr,
			TLSConfig: &tls.Config{
				Certificates: []tls.Certificate{cert},
			},
		}

		go func() {
			log.Printf("HTTPS server started on port %s\n", p.addr)
			if err := p.server.ServeTLS(listener, "", ""); err != nil && !errors.Is(err, http.ErrServerClosed) {
				log.Printf("HTTPS server failed: %s\n", err)
			}
		}()
	} else {
		p.server = &http.Server{Addr: p.addr}
		go func() {
			log.Printf("HTTP server started on port %s\n", p.addr)
			if err := p.server.Serve(listener); err != nil && !errors.Is(err, http.ErrServerClosed) {
				log.Printf("HTTP server failed: %s\n", err)
			}
		}()
	}

	return nil
}

// Stop 停止双向服务器。
func (p *BiSvr) Stop() error {
	if p.server != nil {
		if err := p.server.Shutdown(context.Background()); err != nil {
			return fmt.Errorf("Failed to stop HTTP server: %s", err)
		}
		fmt.Println("HTTP server stopped")
	}
	return nil
}
